<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Chapter&nbsp;6.&nbsp;配置</title>
    <link rel="stylesheet" href="css/html.css" type="text/css">
    <meta name="generator" content="DocBook XSL Stylesheets V1.65.1">
    <link rel="home" href="index.html" title="JBoss jBPM 3.1">
    <link rel="up" href="index.html" title="JBoss jBPM 3.1">
    <link rel="previous" href="deployment.html" title="Chapter&nbsp;5.&nbsp;Deployment">
    <link rel="next" href="persistence.html" title="Chapter&nbsp;7.&nbsp;Persistence">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
    <table width="100%" summary="Navigation header">
        <tr>
            <th colspan="3" align="center">Chapter&nbsp;6.&nbsp;配置</th>
        </tr>
        <tr>
            <td width="20%" align="left"><a accesskey="p" href="deployment.html">Prev</a>&nbsp;</td>
            <th width="60%" align="center">&nbsp;</th>
            <td width="20%" align="right">&nbsp;<a accesskey="n" href="persistence.html">Next</a></td>
        </tr>
    </table>
    <hr>
</div>
<div class="chapter" lang="cn">
<div class="titlepage">
    <div>
        <div><h2 class="title"><a name="configuration"></a>Chapter&nbsp;6.&nbsp;配置</h2></div>
    </div>
    <div></div>
</div>
<p>The simplest way to configure jBPM is by putting the <tt class="literal">jbpm.cfg.xml</tt>
    configuration file in the root of the classpath. If that file is not found as a
    resource, the default minimal configuration will be used that is included in the
    jbpm library. Note that the minimal configuration does not have any configurations
    for persistence.
</p>

<p>The jBPM configuration is represented by the java class <tt class="literal">org.jbpm.JbpmConfiguration</tt>.
    Most easy way to get a hold of the JbpmConfiguration is to make use of the singleton
    instance method <tt class="literal">JbpmContext.getInstance()</tt>.
</p>

<p>If you want to load a configuraiton from another source, you can use the
    <tt class="literal">JbpmConfiguration.parseXxxx</tt> methods.
</p>
<pre class="programlisting">static JbpmConfinguration jbpmConfiguration = JbpmConfinguration.getInstance();</pre>
<p>The JbpmConfiguration is threadsafe and hence can be kept in a static member. All threads can use
    the JbpmConfiguration as a factory for JbpmContext objects. A JbpmContext typically represents one
    transaction. The JbpmContext makes services available inside of a context block.
    A context block looks like this:
</p><pre class="programlisting">JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
  // This is what we call a context block.
  // Here you can perform workflow operations

} finally {
  jbpmContext.close();
}</pre>
<p>The <tt class="literal">JbpmContext</tt> makes a set of services and the configuration available
    to jBPM. These services are configured in the <tt class="literal">jbpm.cfg.xml</tt> configuration file and
    make it possible for
    jBPM to run in any Java environment and use whatever services are available in that environment.
</p>

<p>Here's a typical configuration for the JbpmContext as you can find it in
    <tt class="literal">src/config.files/jbpm.cfg.xml</tt>:
</p><pre class="programlisting">&lt;jbpm-configuration&gt;

  &lt;jbpm-context&gt;
    &lt;service name='persistence' factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' /&gt;
    &lt;service name='message' factory='org.jbpm.msg.db.DbMessageServiceFactory' /&gt;
    &lt;service name='scheduler' factory='org.jbpm.scheduler.db.DbSchedulerServiceFactory' /&gt;
    &lt;service name='logging' factory='org.jbpm.logging.db.DbLoggingServiceFactory' /&gt;
    &lt;service name='authentication' factory='org.jbpm.security.authentication.DefaultAuthenticationServiceFactory' /&gt;
  &lt;/jbpm-context&gt;

  &lt;!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar --&gt;
  &lt;string name='resource.hibernate.cfg.xml' value='hibernate.cfg.xml' /&gt;
  &lt;!-- &lt;string name='resource.hibernate.properties' value='hibernate.properties' /&gt; --&gt;
  &lt;string name='resource.business.calendar' value='org/jbpm/calendar/jbpm.business.calendar.properties' /&gt;
  &lt;string name='resource.default.modules' value='org/jbpm/graph/def/jbpm.default.modules.properties' /&gt;
  &lt;string name='resource.converter' value='org/jbpm/db/hibernate/jbpm.converter.properties' /&gt;
  &lt;string name='resource.action.types' value='org/jbpm/graph/action/action.types.xml' /&gt;
  &lt;string name='resource.node.types' value='org/jbpm/graph/node/node.types.xml' /&gt;
  &lt;string name='resource.parsers' value='org/jbpm/jpdl/par/jbpm.parsers.xml' /&gt;
  &lt;string name='resource.varmapping' value='org/jbpm/context/exe/jbpm.varmapping.xml' /&gt;

  &lt;int name='jbpm.byte.block.size' value="1024" singleton="true" /&gt;
  &lt;bean name='jbpm.task.instance.factory' class='org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl' singleton='true' /&gt;
  &lt;bean name='jbpm.variable.resolver' class='org.jbpm.jpdl.el.impl.JbpmVariableResolver' singleton='true' /&gt;
  &lt;long name='jbpm.msg.wait.timout' value='5000' singleton='true' /&gt;

&lt;/jbpm-configuration&gt;</pre>
<p>In this configuration file you can see 3 parts:
</p>

<div class="itemizedlist">
    <ul type="disc">
        <li><p>The first parse configures the jbpm context with a set of service
            implementations. The possible configuration options are covered in the chapters
            that cover the specific service implementations.
        </p></li>
        <li><p>The second part are all mappings of references to configuration
            resources. These resource references can be updated if you want to customize
            one of these configuration files. Typically, you make a copy the default configuration
            which is in the <tt class="literal">jbpm-3.x.jar</tt> and put it somewhere on the classpath.
            Then you update the reference in this file and jbpm will use your customized version
            of that configuration file.
        </p></li>
        <li><p>The third part are some miscallanious configurations used in jbpm.
            These configuration options are described in the chapters that cover the
            specific topic.
        </p></li>
    </ul>
</div>
<p>The default configured set of services is targetted at a simple webapp environment
    and minimal dependencies. The persistence service will obtain a jdbc connection and all
    the other services will use the same connection to perform their services. So all of you
    workflow operations are centralized into 1 transaction on A JDBC connection without the
    need for a transaction manager.
</p>

<p><tt class="literal">JbpmContext</tt> contains convenience methods for most of the common
    process operations:
</p><pre class="programlisting">  public void deployProcessDefinition(ProcessDefinition processDefinition) {...}
  public List getTaskList() {...}
  public List getTaskList(String actorId) {...}
  public List getGroupTaskList(List actorIds) {...}
  public TaskInstance loadTaskInstance(long taskInstanceId) {...}
  public TaskInstance loadTaskInstanceForUpdate(long taskInstanceId) {...}
  public Token loadToken(long tokenId) {...}
  public Token loadTokenForUpdate(long tokenId) {...}
  public ProcessInstance loadProcessInstance(long processInstanceId) {...}
  public ProcessInstance loadProcessInstanceForUpdate(long processInstanceId) {...}
  public ProcessInstance newProcessInstance(String processDefinitionName) {...}
  public void save(ProcessInstance processInstance) {...}
  public void save(Token token) {...}
  public void save(TaskInstance taskInstance) {...}
  public void setRollbackOnly() {...}</pre>
<p>Note that the <tt class="literal">XxxForUpdate</tt> methods will register the loaded
    object for auto-save so that you don't have to call one of the save methods
    explicitely.
</p>

<p>It's possible to specify multiple <tt class="literal">jbpm-context</tt>s, but then you have
    to make sure that each <tt class="literal">jbpm-context</tt> is given a unique <tt class="literal">name</tt>
    attribute. Named contexts can be retrieved with <tt class="literal">JbpmConfiguration.createContext(String
    name);</tt>
</p>

<p>A <tt class="literal">service</tt> element specifies the name of a service and the service factory
    for that service. The service will only be created in case it's asked for with
    <tt class="literal">JbpmContext.getServices().getService(String name)</tt>.
</p>

<p>The factories
    can also be specified as an element instead of an attribute. That might be necessary to
    inject some configuration information in the factory objects. The component responsible
    for parsing the XML, creating and wiring the objects is called the object factory.
</p>

<div class="section" lang="cn">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="configurationproperties"></a>6.1.&nbsp;配置属性</h2></div>
        </div>
        <div></div>
    </div>
    <p><span class="bold"><b>jbpm.byte.block.size</b></span>:
        File attachments and binary variables are stored in the database. Not as blobs, but as a list of fixed sized
        binary objects.
        This is done to improve portability amongst different databases and improve overall embeddability of jBPM. This
        parameter
        controls the size of the fixed length chunks.
    </p>

    <p><span class="bold"><b>jbpm.task.instance.factory</b></span>:
        To customize the way that task instances are created, specify a fully qualified class name in this property.
        This might be
        necessary when you want to customize the TaskInstance bean and add new properties to it. See also <a
            href="taskmanagement.html#customizingtaskinstances" title="11.10.&nbsp;Customizing task instances">Section&nbsp;11.10,
        &#8220;Customizing task instances&#8221;</a>
        The specified class should implement org.jbpm.taskmgmt.TaskInstanceFactory.
    </p>

    <p><span class="bold"><b>jbpm.variable.resolver</b></span>:
        To customize the way that jBPM will look for the first term in JSF-like expressions.
    </p>

    <p><span class="bold"><b>jbpm.msg.wait.timout</b></span>:
        To customize the time inbetween polls for messages.
    </p></div>
<div class="section" lang="cn">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="configurationfiles"></a>6.2.&nbsp;配置文件
            </h2></div>
        </div>
        <div></div>
    </div>
    <p>Here's a short description of all the configuration files that are customizable in jBPM.
    </p>

    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="hibernatecfgxmlfile"></a>6.2.1.&nbsp;Hibernate cfg xml file</h3></div>
            </div>
            <div></div>
        </div>
        <p>This file contains hibernate configurations and references to the
            hibernate mapping resource files.</p>

        <p>Location: <tt class="literal">hibernate.cfg.xml</tt> unless specified
            otherwise in the jbpm.hibernate.cfg.xml property in the jbpm.properties file.
            In the jbpm project the default hibernate cfg xml file is located in
            directory <tt class="literal">src/config.files/hibernate.cfg.xml</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="hibernatequeriesconfigurationfile"></a>6.2.2.&nbsp;Hibernate queries
                    configuration file</h3></div>
            </div>
            <div></div>
        </div>
        <p>This file contains hibernate queries that are used in the jBPM
            sessions <tt class="literal">org.jbpm.db.*Session</tt>.
        </p>

        <p>Location: <tt class="literal">org/jbpm/db/hibernate.queries.hbm.xml</tt>
        </p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypesconfigurationfile"></a>6.2.3.&nbsp;Node types configuration
                    file</h3></div>
            </div>
            <div></div>
        </div>
        <p>This file contains the mapping of XML node elements to
            Node implementation classes.
        </p>

        <p>Location: <tt class="literal">org/jbpm/graph/node/node.types.xml</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="actiontypesconfigurationfile"></a>6.2.4.&nbsp;Action types configuration
                    file</h3></div>
            </div>
            <div></div>
        </div>
        <p>This file contains the mapping of XML action elements to
            Action implementation classes.
        </p>

        <p>Location: <tt class="literal">org/jbpm/graph/action/action.types.xml</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="businesscalendarconfigurationfile"></a>6.2.5.&nbsp;Business calendar
                    configuration file</h3></div>
            </div>
            <div></div>
        </div>
        <p>Contains the definition of business hours and free time.</p>

        <p>Location: <tt class="literal">org/jbpm/calendar/jbpm.business.calendar.properties</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="variablemappingconfigurationfile"></a>6.2.6.&nbsp;Variable mapping
                    configuration file</h3></div>
            </div>
            <div></div>
        </div>
        <p>Specifies how the values of the process variables (java objects) are
            converted to variable instances for storage in the jbpm database.</p>

        <p>Location: <tt class="literal">org/jbpm/context/exe/jbpm.varmapping.xml</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="converterconfigurationfile"></a>6.2.7.&nbsp;Converter configuration file
                </h3></div>
            </div>
            <div></div>
        </div>
        <p>Specifies the id-to-classname mappings. The id's are stored in the database.
            The org.jbpm.db.hibernate.ConverterEnumType is used to map the ids to the singleton
            objects.</p>

        <p>Location: <tt class="literal">org/jbpm/db/hibernate/jbpm.converter.properties</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="defaultmodulesconfigurationfile"></a>6.2.8.&nbsp;Default modules
                    configuration file</h3></div>
            </div>
            <div></div>
        </div>
        <p>specifies which modules are added to a new ProcessDefinition by default.</p>

        <p>Location: <tt class="literal">org/jbpm/graph/def/jbpm.default.modules.properties</tt></p></div>
    <div class="section" lang="cn">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="parsersconfigurationfile"></a>6.2.9.&nbsp;Process archive parsers
                    configuration file</h3></div>
            </div>
            <div></div>
        </div>
        <p>specifies the phases of process archive parsing</p>

        <p>Location: <tt class="literal">org/jbpm/jpdl/par/jbpm.parsers.xml</tt></p></div>
</div>
<div class="section" lang="cn">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="objectfactory"></a>6.3.&nbsp;对象工厂</h2></div>
        </div>
        <div></div>
    </div>
    <p>The object factory can create objects according to a beans-like xml configuration file.
        The configuration file specifies how objects should be created, configured and wired together
        to form a complete object graph. The object factory can inject the configurations and other
        beans into a bean.
    </p>

    <p>In its simplest form, the object factory is able to create basic types and java beans
        from such a configuration:
    </p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance"/&gt;
  &lt;string name="greeting"&gt;hello world&lt;/string&gt;
  &lt;int name="answer"&gt;42&lt;/int&gt;
  &lt;boolean name="javaisold"&gt;true&lt;/boolean&gt;
  &lt;float name="percentage"&gt;10.2&lt;/float&gt;
  &lt;double name="salary"&gt;100000000.32&lt;/double&gt;
  &lt;char name="java"&gt;j&lt;/char&gt;
  &lt;null name="dusttodust" /&gt;
&lt;/beans&gt;

---------------------------------------------------------

ObjectFactory of = ObjectFactory.parseXmlFromAbove();
assertEquals(TaskInstance.class, of.getNewObject("task").getClass());
assertEquals("hello world", of.getNewObject("greeting"));
assertEquals(new Integer(42), of.getNewObject("answer"));
assertEquals(Boolean.TRUE, of.getNewObject("javaisold"));
assertEquals(new Float(10.2), of.getNewObject("percentage"));
assertEquals(new Double(100000000.32), of.getNewObject("salary"));
assertEquals(new Character('j'), of.getNewObject("java"));
assertNull(of.getNewObject("dusttodust"));</pre>
    <p>Also you can configure lists:</p><pre class="programlisting">&lt;beans&gt;
  &lt;list name="numbers"&gt;
    &lt;string&gt;one&lt;/string&gt;
    &lt;string&gt;two&lt;/string&gt;
    &lt;string&gt;three&lt;/string&gt;
  &lt;/list&gt;
&lt;/beans&gt;</pre>
    <p>and maps</p><pre class="programlisting">&lt;beans&gt;
  &lt;map name="numbers"&gt;
    &lt;entry&gt;&lt;key&gt;&lt;int&gt;1&lt;/int&gt;&lt;/key&gt;&lt;value&gt;&lt;string&gt;one&lt;/string&gt;&lt;/value&gt;&lt;/entry&gt;
    &lt;entry&gt;&lt;key&gt;&lt;int&gt;2&lt;/int&gt;&lt;/key&gt;&lt;value&gt;&lt;string&gt;two&lt;/string&gt;&lt;/value&gt;&lt;/entry&gt;
    &lt;entry&gt;&lt;key&gt;&lt;int&gt;3&lt;/int&gt;&lt;/key&gt;&lt;value&gt;&lt;string&gt;three&lt;/string&gt;&lt;/value&gt;&lt;/entry&gt;
  &lt;/map&gt;
&lt;/beans&gt;</pre>
    <p>Beans can be configured with direct field injection and via property setters.</p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" &gt;
    &lt;field name="name"&gt;&lt;string&gt;do dishes&lt;/string&gt;&lt;/field&gt;
    &lt;property name="actorId"&gt;&lt;string&gt;theotherguy&lt;/string&gt;&lt;/property&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</pre>
    <p>Beans can be referenced. The referenced object doesn't have to be a bean,
        it can be a string, integer or any other object.
    </p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="a" class="org.jbpm.A" /&gt;
  &lt;ref name="b" bean="a" /&gt;
&lt;/beans&gt;</pre>
    <p>Beans can be constructed with any constructor</p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" &gt;
    &lt;constructor&gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;do dishes&lt;/string&gt;
      &lt;/parameter&gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;theotherguy&lt;/string&gt;
      &lt;/parameter&gt;
    &lt;/constructor&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</pre>
    <p>... or with a factory method on a bean ...</p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="taskFactory" 
         class="org.jbpm.UnexistingTaskInstanceFactory" 
         singleton="true"/&gt;

  &lt;bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" &gt;
    &lt;constructor factory="taskFactory" method="createTask" &gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;do dishes&lt;/string&gt;
      &lt;/parameter&gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;theotherguy&lt;/string&gt;
      &lt;/parameter&gt;
    &lt;/constructor&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</pre>
    <p>... or with a static factory method on a class ...</p><pre class="programlisting">&lt;beans&gt;
  &lt;bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" &gt;
    &lt;constructor factory-class="org.jbpm.UnexistingTaskInstanceFactory" method="createTask" &gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;do dishes&lt;/string&gt;
      &lt;/parameter&gt;
      &lt;parameter class="java.lang.String"&gt;
        &lt;string&gt;theotherguy&lt;/string&gt;
      &lt;/parameter&gt;
    &lt;/constructor&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</pre>
    <p>Each named object can be marked as singleton with the attribute <tt class="literal">singleton="true"</tt>.
        That means that a given object factory will always return the same object for each request. Note that
        singletons are not shared between different object factories.
    </p>

    <p>The singleton feature causes the differentiation between the methods <tt class="literal">getObject</tt>
        and <tt class="literal">getNewObject</tt>. Typical users of the object factory will use the
        <tt class="literal">getNewObject</tt>. This means that first the object factory's object cache is cleared
        before the new object graph is constructed. During construction of the object graph, the non-singleton
        objects are stored in the object factory's object cache to allow for shared references to one object.
        The singleton object cache is different from the plain object cache. The singleton cache is never
        cleared, while the plain object cache is cleared at the start of every <tt class="literal">getNewObject</tt>
        method.
    </p></div>
</div>
<div class="navfooter">
    <hr>
    <table width="100%" summary="Navigation footer">
        <tr>
            <td width="40%" align="left"><a accesskey="p" href="deployment.html">Prev</a>&nbsp;</td>
            <td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
            <td width="40%" align="right">&nbsp;<a accesskey="n" href="persistence.html">Next</a></td>
        </tr>
        <tr>
            <td width="40%" align="left" valign="top">Chapter&nbsp;5.&nbsp;部署&nbsp;</td>
            <td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
            <td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;7.&nbsp;持久化</td>
        </tr>
    </table>
</div>
</body>
</html>